package com.sunlands.deskmate.message.handler.receiver.impl;

import com.sunlands.deskmate.channel.ChannelInfo;
import com.sunlands.deskmate.channel.ChannelManager;
import com.sunlands.deskmate.constant.YN;
import com.sunlands.deskmate.message.entity.Messages;
import com.sunlands.deskmate.message.handler.receiver.Receiver;
import io.netty.channel.Channel;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RMapCache;
import org.springframework.stereotype.Component;
import java.util.Objects;
import java.util.concurrent.TimeUnit;
import static com.sunlands.deskmate.channel.ChannelManager.*;


/**
 * @author anjunling@sunlands.com
 */
@Slf4j
@Component
public class HeartBeatMessageReceiver implements Receiver {

    @Override
    public void receive(Channel channel, Messages message) {
//        message.setAckId(IdGenerator.id());
//        String createDateTime = message.getCreateTime();
        //消息回执
        ChannelInfo currentChannelInfo = channel.attr(CHANNEL_INFO).get();
        Channel localChannel = ChannelManager.getChannel(currentChannelInfo.getSessionKey());

        log.info("心跳消息 channel = {}", currentChannelInfo);
        if (!validChannel(currentChannelInfo, localChannel)) {
            log.info("心跳通道非法，进行关闭 currentChannelInfo = {} localChannel = {}", currentChannelInfo, localChannel);
            channel.close();
            return;
        }
        //记录APP状态，是否在前端运行 1前台运行，0后台运行,更新channel心跳时间，3次收不到心跳，通道会自动关闭
        int topRun = Integer.parseInt(message.getMessage());
        channel.attr(TOP_KEY).set(topRun);
        channel.attr(HEART_TIME).set(System.currentTimeMillis());

        //修改redis channel
        RMapCache<String, ChannelInfo> redisChannelStore = getRedisChannelStore();
        ChannelInfo existChannelInfo = redisChannelStore.get(currentChannelInfo.getSessionKey());

        log.info("existChannelInfo = {} message = {}", existChannelInfo, message);
        if (Objects.nonNull(existChannelInfo)
                && Objects.nonNull(message.getMessage())
                && !Integer.valueOf(message.getMessage()).equals(existChannelInfo.getTopRun())) {
            boolean remove = redisChannelStore.remove(existChannelInfo.getSessionKey(), existChannelInfo);
            existChannelInfo.setTopRun(topRun);
            if(topRun == YN.N.code){
                existChannelInfo.setBackRunTime(System.currentTimeMillis());
            } else {
                existChannelInfo.setBackRunTime(0L);
            }
            ChannelInfo ifAbsent = redisChannelStore.putIfAbsent(existChannelInfo.getSessionKey(), existChannelInfo, REDIS_CHANNEL_TIME_OUT, TimeUnit.DAYS, REDIS_CHANNEL_MAX_IDLE_TIME, TimeUnit.MINUTES);
            log.info("用户前后台切换，修改reids channel 结果 remove = {} ifAbsent = {} channelInfo = {}", remove, ifAbsent, existChannelInfo);
            ChannelManager.userOnline(existChannelInfo.getUserId(), existChannelInfo.getTopRun(), existChannelInfo.getCreateTime(), existChannelInfo.getBackRunTime());
        }

        //回执
//        Messages msgEntity = Messages.builder()
//                .type(MessageType.ACK.getType())
//                .ackId(message.getAckId())
//                .createTime(createDateTime)
//                .toId(message.getFromUserId())
//                .requestId(message.getRequestId())
//                .build();
//        webSocketServerHandler.ack(channel, msgEntity);
    }

    /**
     * 是否有效通道 true 是  false 不是
     *
     * @param currentChannelInfo currentChannelInfo
     * @param localChannel       localChannel
     * @return boolean
     */
    private boolean validChannel(ChannelInfo currentChannelInfo, Channel localChannel) {
        return Objects.nonNull(localChannel) && localChannel.attr(CHANNEL_INFO).get().getCreateTime() == currentChannelInfo.getCreateTime();
    }


}
